﻿using FrameworkCore.Migrations.Data;
using Microsoft.EntityFrameworkCore.Query;
using System.Linq.Expressions;

namespace FrameworkCore.Migrations;

public interface IAiBLSmartEduDataProvider
{
    #region 创建数据库
    /// <summary>
    /// 如果数据库不存在则创建
    /// </summary>
    /// <param name="connectionString">数据库连接串</param>
    /// <returns></returns>
    bool CreateDatabaseIfNotExists(string? connectionString = default);

    /// <summary>
    /// 数据库名
    /// </summary>
    string DatabaseName { get; }

    /// <summary>
    /// 数据库连接串
    /// </summary>
    string ConnectionString { get; }

    /// <summary>
    /// 查询数据库是否存在
    /// </summary>
    /// <param name="databaseName">数据库名</param>
    /// <param name="connectionString">数据库连接串</param>
    /// <returns></returns>
    bool DatabaseExists(string? databaseName = default, string? connectionString = default);
    #endregion

    #region 增删改
    /// <summary>
    /// 将记录插入表中。返回带有自增主键的插入实体。
    /// </summary>
    /// <typeparam name="TEntity">要插入的实体</typeparam>
    /// <param name="entity">实体类型</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>
    /// 表示异步操作的任务
    /// 任务结果包含插入的实体
    /// </returns>
    Task<TEntity> InsertEntityAsync<TEntity>(TEntity entity, CancellationToken cancellationToken = default)
        where TEntity : BaseEntity;

    /// <summary>
    /// 将记录插入表中。返回带有自增主键的插入实体。
    /// </summary>
    /// <param name="entity">要插入的实体</param>
    /// <typeparam name="TEntity">实体类型</typeparam>
    /// <returns>插入的实体</returns>
    TEntity InsertEntity<TEntity>(TEntity entity) 
        where TEntity : BaseEntity;

    /// <summary>
    /// 使用实体参数的值更新表中的记录。
    /// 根据主键值匹配实体确定要更新的记录。
    /// </summary>
    /// <param name="entity">带有更新数据的实体</param>
    /// <typeparam name="TEntity">实体类型</typeparam>
    void UpdateEntity<TEntity>(TEntity entity) 
        where TEntity : BaseEntity;

    /// <summary>
    /// 使用实体参数的值更新表中的记录。
    /// 根据主键值匹配实体确定要更新的记录。
    /// </summary>
    /// <param name="entities">带有更新数据的实体集合</param>
    /// <typeparam name="TEntity">实体类型</typeparam>
    void UpdateEntities<TEntity>(IEnumerable<TEntity> entities)
        where TEntity : BaseEntity;

    /// <summary>
    /// 根据条件在表中执行批量修改记录操作。
    /// </summary>
    /// <typeparam name="TEntity">实体类型</typeparam>
    /// <param name="setPropertyCalls">修改的列</param>
    /// <param name="predicate">用于修改每个元素条件的函数</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// 表示异步操作的任务
    /// 任务结果包含修改的记录数
    /// <returns></returns>
    Task<int> BulkUpdateEntitiesAsync<TEntity>(
        Expression<Func<SetPropertyCalls<TEntity>, SetPropertyCalls<TEntity>>> setPropertyCalls,
    Expression<Func<TEntity, bool>> predicate,
        CancellationToken cancellationToken = default)
        where TEntity : BaseEntity;

    /// <summary>
    /// 根据条件在表中执行批量修改记录操作。
    /// </summary>
    /// <typeparam name="TEntity">实体类型</typeparam>
    /// <param name="setPropertyCalls">修改的列</param>
    /// <param name="predicate">用于修改每个元素条件的函数</param>
    /// 修改的记录数
    /// <returns></returns>
    int BulkUpdateEntities<TEntity>(
        Expression<Func<SetPropertyCalls<TEntity>, SetPropertyCalls<TEntity>>> setPropertyCalls,
        Expression<Func<TEntity, bool>> predicate)
        where TEntity : BaseEntity;

    /// <summary>
    /// 删除表中的记录。要删除的记录通过与实体对象的主键值匹配来确定。
    /// </summary>
    /// <param name="entity">删除操作的实体</param>
    /// <typeparam name="TEntity">实体类型</typeparam>
    void DeleteEntity<TEntity>(TEntity entity)
        where TEntity : BaseEntity;

    /// <summary>
    /// 在表中执行批量删除记录操作。
    /// </summary>
    /// <param name="entities">要删除的实体集合</param>
    /// <typeparam name="TEntity">实体类型</typeparam>
    void BulkDeleteEntities<TEntity>(IList<TEntity> entities)
        where TEntity : BaseEntity;

    /// <summary>
    /// 根据条件在表中执行批量删除记录操作。(物理删除)
    /// </summary>
    /// <param name="predicate">用于测试每个元素条件的函数</param>
    /// <typeparam name="TEntity">实体类型</typeparam>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>
    /// 表示异步操作的任务
    /// 任务结果包含删除的记录数
    /// </returns>
    Task<int> BulkDeleteEntitiesAsync<TEntity>(Expression<Func<TEntity, bool>> predicate, CancellationToken cancellationToken = default)
        where TEntity : BaseEntity;

    /// <summary>
    /// 根据条件在表中执行批量删除记录操作。
    /// </summary>
    /// <param name="predicate">用于测试每个元素条件的函数</param>
    /// <typeparam name="TEntity">实体类型</typeparam>
    /// <returns>
    /// 删除的记录数
    /// </returns>
    int BulkDeleteEntities<TEntity>(
        Expression<Func<TEntity, bool>> predicate)
        where TEntity : BaseEntity;


    /// <summary>
    /// 对实体集合执行批量插入操作。
    /// </summary>
    /// <param name="entities">要插入的实体集合</param>
    /// <typeparam name="TEntity">实体类型</typeparam>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>表示异步操作的任务</returns>
    Task BulkInsertEntitiesAsync<TEntity>(IEnumerable<TEntity> entities, CancellationToken cancellationToken = default)
        where TEntity : BaseEntity;

    /// <summary>
    /// 对实体集合执行批量插入操作。
    /// </summary>
    /// <param name="entities">要插入的实体集合</param>
    /// <typeparam name="TEntity">实体类型</typeparam>
    void BulkInsertEntities<TEntity>(IEnumerable<TEntity> entities)
        where TEntity : BaseEntity;

    /// <summary>
    /// 保存
    /// </summary>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns></returns>
    Task<int> SaveChangesAsync(CancellationToken cancellationToken = default);

    /// <summary>
    /// 保存
    /// </summary>
    /// <returns></returns>
    int SaveChanges();

    #endregion

    #region 查询
    IQueryable<TEntity> Query<TEntity>() where TEntity : BaseEntity;
    #endregion
}
